#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <dxgi.h>

#pragma comment(lib, "dxgi.lib") // Ensure linking with dxgi.lib for DXGI interface

/**
 * @brief Get the first GPU model using DXGI.
 *
 * Retrieves the description information of the first display adapter (GPU) through the DirectX Graphics Infrastructure (DXGI) interface.
 *
 * @return Returns a string of the first GPU model. If no GPU is detected, returns an empty string.
 */
std::string GetGPUModel() {
    IDXGIFactory* pFactory = nullptr; // DXGI factory pointer

    // Create DXGI factory
    if (FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory)))) {
        std::cerr << "Failed to create DXGI factory" << std::endl;
        return ""; // Return empty string if factory creation fails
    }

    IDXGIAdapter* pAdapter = nullptr; // DXGI adapter pointer

    // Get the first display adapter
    if (pFactory->EnumAdapters(0, &pAdapter) == DXGI_ERROR_NOT_FOUND) {
        pFactory->Release(); // Release factory resources if no adapter found
        return ""; // Return empty string
    }

    // Get adapter description
    DXGI_ADAPTER_DESC adapterDesc;
    pAdapter->GetDesc(&adapterDesc);

    // Convert wide string to normal string using WideCharToMultiByte
    int bufferSize = WideCharToMultiByte(CP_UTF8, 0, adapterDesc.Description, -1, NULL, 0, NULL, NULL);
    std::string gpuName(bufferSize, 0);
    WideCharToMultiByte(CP_UTF8, 0, adapterDesc.Description, -1, &gpuName[0], bufferSize, NULL, NULL);

    pAdapter->Release(); // Release adapter resources
    pFactory->Release(); // Release factory resources

    return gpuName; // Return GPU model
}
